/****************************************************************************
 * Copyright (C) 2009-2010 SciTouch LLC
 * 
 * This file is part of Indigo toolkit.
 * 
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 3 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 ***************************************************************************/

// dingow32test.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <stdio.h>
#include "dingow32test.h"

#include "../c/dingo_c.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_DINGOW32TEST, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DINGOW32TEST));

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DINGOW32TEST));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_DINGOW32TEST);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

#include <cairo-win32.h>

void Draw1 (HWND hWnd, HDC hdc, const PAINTSTRUCT& ps)
{
   cairo_surface_t *surface;
   cairo_t *cr;
   surface = cairo_win32_surface_create(hdc);
   cr = cairo_create(surface);
   cairo_set_source_rgb(cr, 1, 1, 1);
   cairo_paint(cr);

   LOGFONTW lf;
   lf.lfHeight = 1;
   lf.lfWidth = 0;
   lf.lfEscapement = 0;
   lf.lfOrientation = 0;
   lf.lfWeight = FW_NORMAL;
   lf.lfItalic = false;
   lf.lfUnderline = false;
   lf.lfStrikeOut = false;
   lf.lfCharSet = DEFAULT_CHARSET;
   lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
   lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
   lf.lfQuality = CLEARTYPE_QUALITY;
   memcpy(lf.lfFaceName, L"Arial", sizeof(L"Arial"));

   cairo_font_face_t *ff = cairo_win32_font_face_create_for_logfontw(&lf);
   cairo_matrix_t font_scale, ctm;
   cairo_matrix_init_identity(&ctm);
   cairo_matrix_init_identity(&font_scale);
   cairo_matrix_scale(&font_scale, 10, 10);
   cairo_font_options_t *fopt = cairo_font_options_create();
   cairo_scaled_font_t*sf = cairo_scaled_font_create(ff, &font_scale, &ctm, fopt);
   cairo_matrix_init_scale(&font_scale, 15, 15);
   cairo_scaled_font_t*sf2 = cairo_scaled_font_create(ff, &font_scale, &ctm, fopt);
   cairo_set_source_rgb(cr, 0, 0, 0);

   const char* txt = "0";
   cairo_set_scaled_font(cr, sf2);
   cairo_text_extents_t ext;
   cairo_text_extents(cr, txt, &ext);
   for (int j = 0; j < 50; ++j)
      for (int i = 0; i < 50; ++i)
      {
         if (j&1)
            cairo_set_scaled_font(cr, sf2);
         else
            cairo_set_scaled_font(cr, sf);

         cairo_move_to(cr, (ext.width * (1.999 + j * 0.0005)) * i + 20, j * (1.5f * ext.height) + 11);
         cairo_show_text(cr, txt);         
      }

   cairo_destroy(cr);
   cairo_surface_write_to_png(surface, "test1.png");
   cairo_surface_destroy(surface);
}

void Draw (HWND hWnd, HDC hdc, const PAINTSTRUCT& ps)
{
   if (!dingoSetOutputHDC((void*)hdc)) 
   {MessageBoxA(hWnd, dingoGetLastError(), "Error", 0);exit(0);}
   if (!dingoSetHighlightThicknessEnabled(1)) 
   {MessageBoxA(hWnd, dingoGetLastError(), "Error", 0);exit(0);}                                           
   if (!dingoSetHighlightColorEnabled(1)) 
   {MessageBoxA(hWnd, dingoGetLastError(), "Error", 0);exit(0);}                                           
   if (!dingoSetImageSize(ps.rcPaint.right, ps.rcPaint.bottom)) 
   {MessageBoxA(hWnd, dingoGetLastError(), "Error", 0);exit(0);}                                           
   if (!dingoLoadMolFromFile("../data/molfiles/complex_DT.mol")) 
   {MessageBoxA(hWnd, dingoGetLastError(), "Error", 0);exit(0);}
   if (!dingoRender()) 
   {MessageBoxA(hWnd, dingoGetLastError(), "Error", 0);exit(0);}
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);

      Draw(hWnd, hdc, ps);

		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}
